home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
m_p
/
povraywb
/
source.lzh
/
pbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-30
|
9KB
|
411 lines
/****************************************************************************
* pbm.c
*
* This module contains the code to read and write the ppm file format.
* The format is as follows:
*
* (header:)
* P6 - ppm packed magic
* wwww hhhh - Width, Height (16 bits, LSB first)
* 255 - max value
*
* (each scanline:)
* llll - Line number (16 bits, LSB first)
* rr gg bb - bytes
*
* from Persistence of Vision Raytracer
* Copyright 1993 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
#include "frame.h"
#include "povproto.h"
void Read_PBM_Image(IMAGE *Image,char *name);
FILE_HANDLE *Get_PBM_File_Handle()
{
FILE_HANDLE *handle;
if ((handle = (FILE_HANDLE *) malloc(sizeof(FILE_HANDLE))) == NULL)
{
fprintf (stderr, "Cannot allocate memory for output file handle\n");
return(NULL);
}
handle->Default_File_Name_p = Default_PBM_File_Name;
handle->Open_File_p = Open_PBM_File;
handle->Write_Line_p = Write_PBM_Line;
handle->Read_Line_p = Read_PBM_Line;
handle->Read_Image_p = Read_PBM_Image;
handle->Close_File_p = Close_PBM_File;
return (handle);
}
char *Default_PBM_File_Name()
{
return ("data.ppm");
}
int Open_PBM_File (handle, name, width, height, buffer_size, mode)
FILE_HANDLE *handle;
char *name;
int *width;
int *height;
int buffer_size;
int mode;
{
int data1, data2;
handle->mode = mode;
handle->filename = name;
switch (mode)
{
case READ_MODE:
if ((handle->file = fopen (name, READ_FILE_STRING)) == NULL)
{
return(0);
}
if (buffer_size != 0)
{
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
if (((data1 = getc(handle->file)) == EOF)
|| ((data2 = getc(handle->file)) == EOF))
return(0);
if((data1 != 'P') || (data2 != '6')) return (0);
if((data1 = getc(handle->file)) == EOF) return (0);
printf("!");
data2 = 0;
data1 = 0;
do
{
data2 *= 10;
data2 += (data1-48);
if((data1 = getc(handle->file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
*width = data2;
data2 = 0;
data1 = 0;
do
{
data2 *= 10;
data2 += (data1-48);
if((data1 = getc(handle->file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
*height = data2;
data2 = 0;
data1 = 0;
do
{
data2 *= 10;
data2 += (data1-48);
if((data1 = getc(handle->file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
if(data2 != 255) return (0);
handle->width = *width;
handle->height = *height;
handle->buffer_size = buffer_size;
break;
case WRITE_MODE:
if ((handle->file = fopen (name, WRITE_FILE_STRING)) == NULL)
return(0);
if (buffer_size != 0)
{
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
fprintf(handle->file,"P6\n%d %d\n%d\n",*width,*height,255);
handle->width = *width;
handle->height = *height;
handle->buffer_size = buffer_size;
break;
case APPEND_MODE:
if ((handle->file = fopen (name, APPEND_FILE_STRING)) == NULL)
return(0);
if (buffer_size != 0)
{
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
handle->buffer_size = buffer_size;
break;
}
return(1);
}
void Write_PBM_Line (handle, line_data, line_number)
FILE_HANDLE *handle;
COLOUR *line_data;
int line_number;
{
register int x;
for (x = 0 ; x < handle->width ; x++)
{
fputc((int) floor (line_data[x].Red * 255.0), handle->file);
fputc((int) floor (line_data[x].Green * 255.0), handle->file);
fputc((int) floor (line_data[x].Blue * 255.0), handle->file);
}
if (handle->buffer_size == 0)
{
fflush(handle->file); /* close and reopen file for */
handle->file = freopen(handle->filename, APPEND_FILE_STRING,
handle->file); /* integrity in case we crash*/
}
}
int Read_PBM_Line (handle, line_data, line_number)
FILE_HANDLE *handle;
COLOUR *line_data;
int *line_number;
{
int data, i, c;
for (i = 0 ; i < handle->width ; i++)
{
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data[i].Red = (DBL) data / 255.0;
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data[i].Green = (DBL) data / 255.0;
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data[i].Blue = (DBL) data / 255.0;
}
return (1);
}
int Read_PBM_Int_Line (handle, line_data, line_number)
FILE_HANDLE *handle;
IMAGE_LINE *line_data;
int *line_number;
{
int data, i, c;
if(*line_number == handle->height) return 0;
if (((line_data->red = (unsigned char *) malloc(handle->width))==NULL) ||
((line_data->green = (unsigned char *) malloc(handle->width))==NULL) ||
((line_data->blue = (unsigned char *) malloc(handle->width))==NULL))
{
fprintf (stderr, "Cannot allocate memory for picture: %s\n", handle->filename);
close_all();
exit(1);
}
for (i = 0 ; i < handle->width ; i++)
{
line_data->red[i] = 0;
line_data->green[i] = 0;
line_data->blue[i] = 0;
}
for (i = 0 ; i < handle->width ; i++)
{
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data->red[i] = (unsigned char) data;
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data->green[i] = (unsigned char) data;
if ((data = getc(handle->file)) == EOF)
return(-1);
line_data->blue[i] = (unsigned char) data;
}
return (1);
}
void Close_PBM_File (handle)
FILE_HANDLE *handle;
{
if(handle->file)
fclose (handle->file);
if (handle->buffer_size != 0)
free (handle->buffer);
}
void Read_PBM_Image(Image, name)
IMAGE *Image;
char *name;
{
int rc, row, data1, data2;
struct Image_Line line;
FILE_HANDLE handle;
if ((handle.file = Locate_File (name, READ_FILE_STRING)) == NULL)
{
fprintf (stderr, "Cannot open pbm file %s\n", name);
close_all();
exit(1);
}
if (((data1 = getc(handle.file)) == EOF)
|| ((data2 = getc(handle.file)) == EOF))
{
fprintf (stderr, "Cannot open pbm file %s\n", name);
close_all();
exit(1);
}
if((data1 != 'P') || (data2 != '6'))
{
fprintf (stderr, "File %s is no pbmfile.\n", name);
close_all();
exit(1);
}
if((data1 = getc(handle.file)) == EOF) return (0);
data2 = 0;
data1 = 48;
do
{
data2 *= 10;
data2 += data1-48;
if((data1 = getc(handle.file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
Image->iwidth = data2;
data2 = 0;
data1 = 48;
do
{
data2 *= 10;
data2 += (data1-48);
if((data1 = getc(handle.file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
Image->iheight = data2;
data2 = 0;
data1 = 48;
do
{
data2 *= 10;
data2 += (data1-48);
if((data1 = getc(handle.file)) == EOF) return (0);
}while((data1 >= '0') && (data1 <= '9'));
if(data2 != 255)
{
fprintf (stderr, "Pbm file %s of wrong scale.\n", name);
close_all();
exit(1);
}
Image->width = (DBL)Image->iwidth;
Image->height = (DBL)Image->iheight;
handle.filename = name;
handle.width = Image->iwidth;
handle.height = Image->iheight;
Image->Colour_Map_Size = 0;
Image->Colour_Map = NULL;
if ((Image->data.rgb_lines = (struct Image_Line *)
malloc(Image->iheight * sizeof (struct Image_Line))) == NULL)
{
fprintf (stderr, "Cannot allocate memory for picture: %s\n", name);
exit(1);
}
row=0;
while ((rc = Read_PBM_Int_Line(&handle, &line, &row)) == 1)
{
Image->data.rgb_lines[row] = line;
row++;
}
fprintf(stdout,"%d\n",row);
fclose (handle.file);
if (rc == 0)
return;
else
{
close_all();
exit(1);
}
}